home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 93 / applic / sdbcom.c < prev    next >
C/C++ Source or Header  |  1987-01-15  |  9KB  |  398 lines

  1. /* SDB - expression compiler
  2.     syntax:
  3.         <expr>        ::= <lor> <EOS>
  4.     <lor>        ::= <land> { '|' <land> }
  5.     <land>        ::= <relat> { '&' <relat> }
  6.     <relat>        ::= <primary> { <relop> <primary> }
  7.     <primary>    ::= <factor> | <unop> <unary>
  8.     <factor>    ::= <number> | <string> | '(' <query> ')'
  9.     <number>    ::= <digit> | <number> <digit>
  10.     <string>    ::= '"' <chars> '"'
  11.     <chars>        ::= nil | <chars> <character>
  12.     <relop>        ::= '=' | '<>' | '<' | '>' | '<=' | '>='
  13.         <unop>        ::= '+' | '-' | '~'
  14. */
  15.  
  16. #include "sdbio.h"
  17.  
  18. extern int dbv_token;
  19. extern char dbv_tstring[];
  20. extern int dbv_tvalue;
  21.  
  22. extern int db_xand();
  23. extern int db_xor();
  24. extern int db_xnot();
  25. extern int db_xlss();
  26. extern int db_xleq();
  27. extern int db_xeql();
  28. extern int db_xgeq();
  29. extern int db_xgtr();
  30. extern int db_xneq();
  31. extern int db_xpush();
  32. extern int db_xstop();
  33.  
  34. static union codecell code[CODEMAX+1];
  35. static int cndx;
  36. static struct sel *selptr;
  37.  
  38. /* compile - compile a boolean expression */
  39. int db_compile(slptr)
  40.   struct sel *slptr;
  41. {
  42.     int result,i;
  43.     union codecell *cptr;
  44.  
  45.     /* save the selection structure pointer */
  46.     selptr = slptr;
  47.  
  48.     /* initialize the code array index */
  49.     cndx = 0;
  50.  
  51.     /* parse the boolean expression */
  52.     if (!expr(&result)) {
  53.     code[cndx++].c_operator = db_xstop;
  54.         freelit(code);
  55.         return (FALSE);
  56.     }
  57.  
  58.     /* terminate the code */
  59.     code[cndx++].c_operator = db_xstop;
  60.  
  61.     /* allocate space for the code array */
  62.     if ((cptr = (union codecell *)malloc(sizeof(union codecell) * cndx)) == NULL) {
  63.         freelit(code);
  64.         return (FALSE);
  65.     }
  66.  
  67.     /* store the code into the code array */
  68.     slptr->sl_where = cptr;
  69.     for (i = 0; i < cndx; i++) {
  70.         (*cptr++).c_operator = code[i].c_operator;
  71.     if (code[i].c_operator == db_xpush)
  72.         (*cptr++).c_operand = code[++i].c_operand;
  73.     }
  74.  
  75.     /* return successfully */
  76.     return (TRUE);
  77. }
  78.  
  79. /* db_fcode - free a code array */
  80. db_fcode(slptr)
  81.   struct sel *slptr;
  82. {
  83.     /* make sure there is a where clause */
  84.     if (slptr->sl_where == NULL)
  85.     return;
  86.  
  87.     /* free the literals */
  88.     freelit(slptr->sl_where);
  89.  
  90.     /* free the code array */
  91.     free(slptr->sl_where);
  92. }
  93.  
  94. /* operator - insert an operator into the code array */
  95. static int operator(opr)
  96.   int (*opr)();
  97. {
  98.     /* insert the operator */
  99.     if (cndx < CODEMAX)
  100.     code[cndx++].c_operator = opr;
  101.     else
  102.         return (db_ferror(CDSIZE));
  103.  
  104.     /* return successfully */
  105.     return (TRUE);
  106. }
  107.  
  108. /* operand - insert an operand into the code array */
  109. static int operand(opr)
  110.   struct operand *opr;
  111. {
  112.     /* insert the push operator */
  113.     if (!operator(db_xpush))
  114.         return (FALSE);
  115.  
  116.     /* insert the operand */
  117.     if (cndx < CODEMAX)
  118.     code[cndx++].c_operand = opr;
  119.     else
  120.         return (db_ferror(CDSIZE));
  121.  
  122.     /* return successfully */
  123.     return (TRUE);
  124. }
  125.  
  126. /* expr - compile an expression */
  127. static int expr(result)
  128.   int *result;
  129. {
  130.     int lval,rval;
  131.  
  132.     if (!land(&lval))
  133.         return (FALSE);
  134.     while (db_token() == '|') {
  135.         db_ntoken();
  136.         if (!land(&rval))
  137.             return (FALSE);
  138.     if (!operator(db_xor))
  139.             return (FALSE);
  140.     }
  141.     *result = lval;
  142.     return (TRUE);
  143. }
  144.  
  145. static int land(result)
  146.   int *result;
  147. {
  148.     int lval,rval;
  149.  
  150.     if (!relat(&lval))
  151.         return (FALSE);
  152.     while (db_token() == '&') {
  153.         db_ntoken();
  154.         if (!relat(&rval))
  155.             return (FALSE);
  156.     if (!operator(db_xand))
  157.             return (FALSE);
  158.     }
  159.     *result = lval;
  160.     return (TRUE);
  161. }
  162.  
  163. static int relat(result)
  164.   int *result;
  165. {
  166.     int lval,rval;
  167.     int tkn;
  168.  
  169.     if (!primary(&lval))
  170.         return (FALSE);
  171.     while (db_token() <= LSS && dbv_token >= GTR) {
  172.         tkn = db_ntoken();
  173.         if (!primary(&rval))
  174.             return (FALSE);
  175.     switch (tkn) {
  176.     case LSS:
  177.         if (!operator(db_xlss))
  178.                 return (FALSE);
  179.         break;
  180.     case LEQ:
  181.         if (!operator(db_xleq))
  182.                 return (FALSE);
  183.         break;
  184.     case EQL:
  185.         if (!operator(db_xeql))
  186.                 return (FALSE);
  187.         break;
  188.     case NEQ:
  189.         if (!operator(db_xneq))
  190.                 return (FALSE);
  191.         break;
  192.     case GEQ:
  193.         if (!operator(db_xgeq))
  194.                 return (FALSE);
  195.         break;
  196.     case GTR:
  197.         if (!operator(db_xgtr))
  198.                 return (FALSE);
  199.         break;
  200.     }
  201.     }
  202.     *result = lval;
  203.     return (TRUE);
  204. }
  205.  
  206. static int primary(result)
  207.   int *result;
  208. {
  209.     int val;
  210.     int tkn;
  211.  
  212.     if (db_token() == '~') {
  213.         tkn = db_ntoken();
  214.     if (!primary(&val))
  215.             return (FALSE);
  216.     switch (tkn) {
  217.     case '~':
  218.         if (!operator(db_xnot))
  219.                 return (FALSE);
  220.         break;
  221.     }
  222.     }
  223.     else
  224.         if (!factor(&val))
  225.             return (FALSE);
  226.     *result = val;
  227.     return (TRUE);
  228. }
  229.  
  230. static int factor(result)
  231.   int *result;
  232. {
  233.     int val;
  234.  
  235.     if (db_token() == '(') {
  236.         db_ntoken();
  237.         if (!expr(&val))
  238.             return (FALSE);
  239.     if (db_token() != ')')
  240.             return (db_ferror(SYNTAX));
  241.         db_ntoken();
  242.     }
  243.     else
  244.         if (!get_operand(&val))
  245.             return (FALSE);
  246.     *result = val;
  247.     return (TRUE);
  248. }
  249.  
  250. /* get_operand - get an operand (number, string, or attribute) */
  251. static int get_operand(result)
  252.   int *result;
  253. {
  254.     /* determine operand type */
  255.     if (db_ntoken() == NUMBER)
  256.     return (get_number(result));
  257.     else if (dbv_token == ID)
  258.     return (get_attr(result));
  259.     else if (dbv_token == STRING)
  260.     return (get_string(result));
  261.     else
  262.     return (db_ferror(SYNTAX));
  263. }
  264.  
  265. /* get_attr - get an attribute argument */
  266. static int get_attr(result)
  267.   int *result;
  268. {
  269.     struct operand *opr;
  270.     char rname[RNSIZE+1],aname[ANSIZE+1];
  271.     char *aptr; int atype,alen;
  272.     
  273.     /* save the attribute name */
  274.     strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
  275.  
  276.     /* check for a "." indicating a qualified attribute name */
  277.     if (db_token() == '.') {
  278.         db_ntoken();
  279.  
  280.         /* the previous ID was really a relation name */
  281.         strcpy(rname,aname);
  282.  
  283.         /* check for the real attribute name */
  284.         if (db_ntoken() != ID)
  285.             return (db_ferror(SYNTAX));
  286.  
  287.         /* save the attribute name */
  288.         strncpy(aname,dbv_tstring,ANSIZE); aname[ANSIZE] = EOS;
  289.  
  290.         /* lookup the attribute name */
  291.         if (!db_sattr(selptr,rname,aname,&atype,&aptr,&alen))
  292.             return (FALSE);
  293.     }
  294.     else
  295.         if (!db_sattr(selptr,NULL,aname,&atype,&aptr,&alen))
  296.             return (FALSE);
  297.  
  298.     /* get a new operand structure */
  299.     if ((opr = (struct operand *)malloc(sizeof(struct operand))) == NULL)
  300.         return (db_ferror(INSMEM));
  301.  
  302.     /* initialize the new operand structure */
  303.     opr->o_type = ATTR;
  304.     opr->o_value.ov_char.ovc_type = atype;
  305.     opr->o_value.ov_char.ovc_string = aptr;
  306.     opr->o_value.ov_char.ovc_length = alen;
  307.  
  308.     /* insert the operand into the code array */
  309.     if (!operand(opr)) {
  310.         free(opr);
  311.         return (FALSE);
  312.     }
  313.  
  314.     /* store operand type */
  315.     *result = atype;
  316.  
  317.     /* return successfully */
  318.     return (TRUE);
  319. }
  320.  
  321. /* get_number - get a numeric operand */
  322. static int get_number(result)
  323.   int *result;
  324. {
  325.     struct operand *opr;
  326.  
  327.     /* get a new operand structure */
  328.     if ((opr = (struct operand *)malloc(sizeof(struct operand))) == NULL)
  329.         return (db_ferror(INSMEM));
  330.  
  331.     /* initialize the new operand structure */
  332.     opr->o_type = LITERAL;
  333.     if ((opr->o_value.ov_char.ovc_string =
  334.             malloc(strlen(dbv_tstring)+1)) == NULL) {
  335.         free(opr);
  336.         return (db_ferror(INSMEM));
  337.     }
  338.     opr->o_value.ov_char.ovc_type = TNUM;
  339.     strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
  340.     opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
  341.  
  342.     /* insert the operand into the code array */
  343.     if (!operand(opr)) {
  344.         free(opr->o_value.ov_char.ovc_string); free(opr);
  345.         return (FALSE);
  346.     }
  347.  
  348.     /* operand type is number */
  349.     *result = TNUM;
  350.  
  351.     /* return successfully */
  352.     return (TRUE);
  353. }
  354.  
  355. /* get_string - get a string operand */
  356. static int get_string(result)
  357.   int *result;
  358. {
  359.     struct operand *opr;
  360.     
  361.     /* get a new operand structure */
  362.     if ((opr = (struct operand *)malloc(sizeof(struct operand))) == NULL)
  363.         return (db_ferror(INSMEM));
  364.  
  365.     /* initialize the new operand structure */
  366.     opr->o_type = LITERAL;
  367.     if ((opr->o_value.ov_char.ovc_string =
  368.             malloc(strlen(dbv_tstring)+1)) == NULL) {
  369.         free(opr);
  370.         return (db_ferror(INSMEM));
  371.     }
  372.     opr->o_value.ov_char.ovc_type = TCHAR;
  373.     strcpy(opr->o_value.ov_char.ovc_string,dbv_tstring);
  374.     opr->o_value.ov_char.ovc_length = strlen(dbv_tstring);
  375.  
  376.     /* insert the operand into the code array */
  377.     if (!operand(opr)) {
  378.         free(opr->o_value.ov_char.ovc_string); free(opr);
  379.         return (FALSE);
  380.     }
  381.  
  382.     /* operand type is character */
  383.     *result = TCHAR;
  384.  
  385.     /* return successfully */
  386.     return (TRUE);
  387. }
  388.  
  389. /* freelit - free the literals in a code array */
  390. static freelit(cptr)
  391.   union codecell *cptr;
  392. {
  393.     for (; (*cptr).c_operator != db_xstop; cptr++)
  394.     if ((*cptr).c_operator == db_xpush)
  395.         if ((*++cptr).c_operand->o_type == LITERAL)
  396.         free((*cptr).c_operand->o_value.ov_char.ovc_string);
  397. }
  398.